"use strict";
////let 变量名：类型=初始值;
//变量名 可以包含 字母数字_$
//数字不能开头
let has = true; //let 变量名：类型=初始值
// let 2has:boolean=true;   //报错  数字不能开头
// let has$:boolean=false;
// let _has:boolean=true;
// let $has:boolean=true;
console.log(has);
has = false;
console.log(has);
// has="你好"; //报错 因为has是boolean类型 不能赋值字符串
//has=123; // 报错
has = !!"你好";
console.log(has);
//number数字类型
let m = 200;
//m="hello"; 报错
m = -200.2;
console.log(m);
//string类型
let str = "hello world";
console.log(str);
//str=10000; 报错
// str=false; 报错
// ""  ''  ``里面不管放任何东西都是字符串
str = `
 <div></div>
 var m=1000;
`;
//定义数组类型
//  变量:类型[]=初始值；
//  变量：Array<类型>=初始值；
let arr = [1, 2, 3, 4, 5];
// arr=["a","b"] //报错
let arr2;
// arr2=[1,2,3] 报错
arr2 = ["1", "2", "3"];
console.log(arr2);
//元组数据类型
let arr3 = [1, 2, "a", true];
//枚举  enum
console.log("--------枚举------------");
var ColorEnum;
(function (ColorEnum) {
    ColorEnum[ColorEnum["Red"] = 0] = "Red";
    ColorEnum[ColorEnum["Yellow"] = 100] = "Yellow";
    ColorEnum[ColorEnum["Blue"] = 101] = "Blue";
    ColorEnum["Black"] = "\u9ED1\u8272";
    ColorEnum["White"] = "\u767D\u8272";
})(ColorEnum || (ColorEnum = {}));
let color = ColorEnum.Red;
console.log(color); //输出1 如果标识符没有赋值，这个标识符的值是下标
color = ColorEnum.Black;
console.log(color); //输出 黑色
color = ColorEnum.Yellow;
console.log(color); //输出100
color = ColorEnum.Blue;
console.log(color); //输出101
color = ColorEnum.White;
console.log(color);
function getColorValue(val) {
    switch (val) {
        case ColorEnum.Blue:
            console.log("蓝色");
            break;
        case ColorEnum.Black:
            console.log("黑色");
            break;
        case ColorEnum.Yellow:
            console.log("黄色");
            break;
        case ColorEnum.Red:
            console.log("红色22");
            break;
        case ColorEnum.White:
            console.log("白色2");
            break;
        default:
            break;
    }
}
color = ColorEnum.Red;
getColorValue(color);
//any 类型
console.log("-------any类型--------");
let obj;
obj = 10000;
console.log(obj);
obj = "你好";
console.log(obj);
//unknown 类型
console.log("-------unknown类型--------");
let obj2;
obj2 = 20000;
console.log(obj2);
obj2 = "你好世界";
console.log(obj2);
//any  unknown的区别
obj = "hello world";
console.log(obj);
let hello;
hello = obj;
//  hello=obj2;// 报错 unknown类型不能给 别变量赋值
console.log("hello:", hello);
//null \undefined类型
console.log("--------null  undefined类型---------");
let info;
info = undefined;
// info="zs"; 报错
// info=100; 报错
let info2;
info2 = null;
//联合类型  类型1 |（管道符）  类型2 |....
console.log("--------联合类型---------");
let val;
val = 100;
console.log(val);
val = "你好";
console.log(val);
val = undefined;
console.log(val);
val = null;
console.log(val);
//void 
console.log("----------void类型-  函数没有返回值---------");
function submit() {
    console.log("这是一个没有返回值的函数");
    // return 10000; 报错
    // return "ok"; 报错
}
submit();
//never类型
console.log("---------never类型-----------");
function error() {
    throw new Error("错误");
    console.log("执行后面代码");
}
//  error();
//无限循环  死循环
function loop() {
    while (true) {
        console.log("执行");
    }
    console.log("执行结束");
}
// loop();
//类型推断  声明变量的时候 不给它指定类型 
console.log("-------类型推断------");
//1、基本类型推断
let x = 100; //推断x为 number类型；
console.log(x);
// x="你好" //报错
let userName = "张三"; //推断为 string类型
// userName=100; 报错
//数组类型推断
let arr5 = [1, 2, 3]; //推断arr5类型为 number[]
// arr5=["a","b"] 报错
//特殊
let arr6 = [1, 2, 3, null];
arr6 = [null, 2, 3];
// ts函数定义
console.log("--------函数定义---------");
// function 函数名(参数1:类型,参数2:类型):返回类型{
//     return 返回值
// }
//声明方式 定义函数
function getUserInfo(name) {
    return "姓名" + name;
    // return 100; //报错 函数返回值是string
}
//表达式 定义函数
let getInfo = function (name) {
    return "姓名" + name;
};
//箭头函数
let getUser = (name) => {
    return "姓名" + name;
};
// let zs= getUserInfo(100);  报错
let zs = getUserInfo("张三");
console.log(zs);
function add() {
}
//ts 函数的可选参数  age为可选参数
function update(name, age, from) {
    console.log(name);
    console.log(age);
    console.log(from);
}
// update("李四",18,"北京"); 报错
update("李四", 20, "北京");
function add2(age, name) {
    console.log(age);
    console.log(name);
}
add2(20, "王五");
//函数的默认参数
function getStudent(name, from = "中国", id = 0) {
    console.log("name", name);
    console.log("id", id);
    console.log("来自", from);
    return id;
}
let id = getStudent("赵六");
//函数剩余参数 剩余参数必须在参数最后
function sum(a, ...c) {
    console.log("c", c);
    return a + c.reduce((pre, cur) => pre + cur); //reduce求和函数
}
let s = sum(1, 2, 3, 4, 5, 6, 7, 8, 9);
console.log(s);
//函数重载  函数名一样 参数不一样
//js（es5） 函数名一样  后面的函数会覆盖掉前面的函数
//ts重载 函数名一样 函数参数不一样
console.log("----------函数重载---------");
function getStudentInfo(nameOrAge) {
    if (typeof nameOrAge === "string") {
        return "姓名" + nameOrAge;
    }
    else {
        return "年龄" + nameOrAge;
    }
}
let zs2 = getStudentInfo("张三");
console.log(zs2);
let age = getStudentInfo(18);
console.log(age);
// getStudentInfo(true); 报错
//函数的类型推断
console.log("----------函数的类型推断---------");
function getStudentInfo2(from = "中国") {
    console.log("来自", from);
}
// getStudentInfo2(100); 报错
getStudentInfo2();
getStudentInfo2("小日子");
//函数返回值 类型推断
function getStudentInfo3(name) {
    return "姓名" + name;
}
var zs3;
zs3 = getStudentInfo3("张三");
console.log(zs3);
// let val2:number=getStudentInfo3("张三");  报错 
console.log("----------类 class---------");
//定义类  class
//constructor作用：初始化属性
class Student {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    //方法
    getName() {
        console.log("我叫", this.name);
        return this.name;
    }
    getAge() {
        return this.age;
    }
}
let zhangsan = new Student("张三", 18);
console.log(zhangsan.name);
console.log(zhangsan.age);
let zsName = zhangsan.getName();
console.log(zsName);
//类的继承  子类继承父类  子类拥有父类的属性和方法（除了私有属性） 继承关键字 extents
console.log("----------类继承---------");
//定义一个动物类 父类
class Animal {
    constructor(name, color) {
        this.name = name;
        this.color = color;
    }
    cry() {
        console.log(this.name + "汪汪汪");
    }
}
//子类Dog 继承了父类
class Dog extends Animal {
    constructor(name, color, age) {
        super(name, color); //调用父类的构造函数
        this.age = age;
    }
    dogCry() {
        //子类调用父类的方法
        super.cry();
    }
}
let wangcai = new Dog("旺财", "白色", 2);
console.log(wangcai.name);
// wangcai.cry();
wangcai.dogCry();
//类的修饰符  public
console.log("----------类修饰符---------");
class Person {
    constructor(name, age, sex) {
        this.name = name;
        this.sex = sex;
        this.age = age;
    }
    static print() {
        console.log("父类的静态方法");
    }
    getAge() {
        console.log("年龄", this.age);
        return this.age;
    }
    getName() {
        return this.name;
    }
}
class Child extends Person {
    constructor(name, age, sex) {
        super(name, age, sex);
    }
    getSubAge() {
        // console.log(this.age); 报错 子类不能访问父类的私有属性
    }
    getSex() {
        //子类访问父类的属性
        return this.sex;
    }
}
//public   公有的属性   外面可以使用  子类也可以使用 本类(类的内部)也可以使用
//protected   受保护的属性 外面不可以使用  子类可以使用  本类(类的内部)也可以使用
// private   私有属性   外面不可以使用  子类不可以使用  本类(类的内部)可以使用
let zhaoliu = new Person("赵六", 18, "男");
console.log(zhaoliu.name); //可以访问
// console.log(zhaoliu.age); //报错 age是父类的私有属性，外界无法访问
// console.log(zhaoliu.sex); //报错 外面不能访问
zhaoliu.getAge();
let wangwu = new Child("王五", 18, "男");
// console.log(wangwu.sex); 报错 sex是父类的受保护的属性，外界无法访问
let sex = wangwu.getSex();
console.log(sex);
Child.print(); //子类继承父类的静态成员
//静态属性
console.log("----------静态属性---------");
class Person2 {
    constructor(name) {
        this.name = name;
    }
    static print() {
        console.log("这是一个静态方法");
    }
}
Person2.from = "来自中国";
//访问静态成员（属性和方法）  类名.成员
console.log(Person2.from);
Person2.from = "来自美国";
console.log(Person2.from);
Person2.print();
//抽象类 使用abstract定义抽象类
console.log("----------抽象类---------");
class AnimalManager {
    constructor(name) {
        this.name = name;
    }
}
class Cat extends AnimalManager {
    constructor(name) {
        super(name);
    }
    cry() {
        console.log("喵喵喵");
    }
}
let xiaohei = new Cat("小猫");
xiaohei.cry();
class Dog2 extends AnimalManager {
    constructor(name) {
        super(name);
    }
    cry() {
        console.log("汪汪汪");
    }
}
let wc = new Dog2("旺财");
wc.cry();
//类可以实现多继承
//接口  定义 使用 interface
console.log("----------接口---------");
const getStuInfo = (student) => {
    console.log(student.name, student.age);
};
// getStuInfo({id:100}); 报错
getStuInfo({ name: "张三", age: 18 });
const zl = { age: 18, name: "张三" };
console.log(zl);
// const addFn:IAdd=(num:number,num2:string)=>{
//     return num+num2;
// }
// //报错
const addFn = (num, num2) => {
    return num + num2;
};
console.log(addFn(1, 2));
// let arr8:IArr=[1,2,3,4] 报错 数组项是string 类型
let arr9 = ["1", "2", "3"];
console.log(arr9);
// var userOject:IObject={
//     name:"张三",
//     age:18
// }  
// 报错 因为对象的值是string类型
var userOject = {
    name: "张三",
    age: "18"
};
//一个类可以实现多个接口
class Person3 {
    constructor(name, age) {
        this.name = name;
        this.age = age;
        this.from = "中国";
    }
    cry() {
        console.log("cry");
    }
}
let xiaobai = {
    name: "小白",
    age: 18,
    color: "白色",
    hobby: "吃东西",
    cry() {
        console.log("喵喵喵");
    }
};
class Cat2 {
    constructor(hobby) {
        this.hobby = hobby;
        this.name = "小猫";
        this.age = 18;
        this.color = "白色";
    }
    cry() {
        console.log("喵喵喵");
    }
}
const responseData = {
    code: 200,
    msg: "请求成功",
    data: [
        {
            id: 1,
            name: "流星花园",
            children: [
                {
                    id: 3,
                    name: "1栋",
                    children: [
                        {
                            id: 8,
                            name: "1单元",
                        }
                    ]
                },
                {
                    id: 4,
                    name: "2栋"
                }
            ]
        },
        {
            id: 2,
            name: "清水湾",
        }
    ]
};
let arr10 = [{ id: 1, title: "北京" }, { id: 2, title: "上海" }];
console.log("----------泛型-------------");
//泛型  定义  类 接口  函数的时候 不指定类型，传入再指定类型   <>传入 
//any和泛型的区别  any没有类型校验 泛型有类型校验
//1、泛型函数
function identity(arg) {
    return arg;
}
let output = identity(10000);
console.log(output);
let output2 = identity("10000");
//封装一个泛型函数   返回数组的长度
function getArrayLength(arg) {
    return arg.length;
}
console.log(getArrayLength([1, 2, 3, 4, 5]));
console.log(getArrayLength(["a", "b", "c"]));
//泛型函数
function Md5(key, value) {
    return key;
}
let output3 = Md5("key", 10000);
console.log(output3);
//使用泛型封装冒泡排序函数
let arr11 = [1, 3, 5, 8, 2, 9];
let arr12 = ["b", "c", "a", "d"];
function bubbleSort(ary) {
    for (var i = 0; i < ary.length; i++) { //正在进行第几次循环
        for (var j = 0; j < ary.length - 1 - i; j++) { //本次循环需要执行几次
            if (ary[j] > ary[j + 1]) {
                var tmp = ary[j];
                ary[j] = ary[j + 1];
                ary[j + 1] = tmp;
            }
        }
    }
    return ary;
}
console.log(arr11);
console.log(bubbleSort(arr11));
console.log(arr12);
console.log(bubbleSort(arr12));
//泛型 类
console.log("----------泛型类----------");
class StudentData {
    constructor() {
        this.list = [];
    }
    add(data) {
        this.list.push(data);
    }
    remove(index) {
        this.list.splice(index, 1);
        return this.list;
    }
    getList() {
        return this.list;
    }
}
// let arr13=[1,2,3,4,5];
const st = new StudentData();
st.add({ name: "张三", age: 18 });
st.add({ name: "李四", age: 20 });
console.log(st.list);
st.remove(0);
console.log(st.list);
var obj3 = { key: "name", value: 1000 };
var md5 = function (key, value) {
    return key;
};
//泛型约束  参数类型 满足某些条件    关键字  extents
console.log("----------泛型约束----------");
function getDataLength(data) {
    return data.length;
}
console.log(getDataLength("hello"));
// console.log(getDataLength(10)); 报错 10没有 length属性
console.log(getDataLength(["a", "b"]));
function getUserList(arr) {
    return arr;
}
console.log(getUserList([{ id: 1, name: "张三" }, { id: 2, name: "李四" }]));
// console.log(getUserList([{id:1,label:"张三"},{id:2,label:"李四"}]));  报错 没有 name属性
// console.log(getUserList(["a","b"])); 报错 没有id name属性
//有一个对象  根据 键返回 它值
function getDataValue(obj, key) {
    return obj[key];
}
//keyof T T所有的属性
//V extends keyof T  ：V继承 T的属性
let outputKey = getDataValue({ id: 1, name: "张三111" }, "name");
// let outputKey=getDataValue({id:1,name:"张三111"},"age"); 报错  没有 age属性
console.log(outputKey);
var obj4 = { value: "1000", label: 20000 };
console.log(obj4);
// var obj5:IData3<string>={value:"1000",label:20000}; 报错 label没指定类型 默认为 string
var obj5 = { value: "1000", label: "200000" };
console.log(obj5);
//类型别名 type
console.log("----------类型别名----------");
let n = 100;
console.log(n);
let str18 = "hello";
console.log(str18);
let user = {
    id: "1000",
    name: "张三"
};
const getUser2 = (val) => {
    return val;
};
let tuples = ["a", 10000];
let parmas = "hello";
parmas = 10000;
let parmas2 = { id: 1000 };
parmas2 = { name: "张三" };
parmas2 = { id: 100, name: "张三" };
console.log(parmas2);
let user2 = {
    id: 100,
    name: "张三",
    age: 18,
    hobby: ["a", "b"],
    sex: "男"
};
let user3 = {
    id: 100,
    name: "张三",
    age: 18,
    hobby: ["a", "b"],
    sex: "男",
    from: "中国"
};
let store = {
    id: 100,
    name: "FCK",
    address: "北京"
};
class AnimalModel {
    constructor(name, age, color) {
        this.name = name;
        this.age = age;
        this.color = color;
    }
}
//类型断言  类型转换 <>    as
console.log("----------类型断言----------");
let str19 = "hello";
let len = str19.length;
let len2 = str19.length;
const house = {};
// house.name="北京"; 报错 house没有name属性
house.name = "北京";
console.log(house.id);
console.log(house.name);
let company = {
    id: 100,
    name: "百度"
};
// company.id=200; 报错 id是只读属性
company.name = "阿里";
console.log(company);
//const断言
let point = [1, 2];
// point[0]=100; 报错  point只读数组
console.log(point);
//非空断言运算符（!）
let token;
sessionStorage.setItem("token", "123456");
token = sessionStorage.getItem("token");
console.log(token);
let username;
function setValue() {
    username = "zs";
}
setValue();
// let nameLen:number=username.length; 报错 username可能为undefined
let nameLen = username.length;
//双重断言   两次转换
let age8 = 18;
let ageValuae = age8;
console.log(ageValuae);
